<?php
namespace Lonicera\core;
class Db{
	private $dbLink;
	protected $queryNum = 0;
	private static $instance;
	protected $PDOStatement;
	//事务数
	protected $transTimes = 0;
	protected $bind = [];
	public $rows = 0;
	
	
	private function __construct($config){
		$this->connect($config);
	}
	
	public static function getInstance($config){
		if(! (self::$instance instanceof self)){ //使用单例模式,构造函数已经私有化,这是统一入口
			self::$instance = new self($config);
		}
		return self::$instance;
	}
	public function connect($config){
		try{
			$this->dbLink = new \PDO($config['dsn'],$config['username'],$config['password'],$config['param']);
		}catch(\PDOException $e){
			throw $e; //此处异常无法处理记录日之后往上抛
		}
		
		return $this->dbLink; //链式调用 创建链接
	}
	
	public function query($sql, $bind=[], $fetchType = \PDO::FETCH_ASSOC){
		if(! $this->dbLink){
			throw new \Exception('数据库链接失败');
		}
		$this->PDOStatement = $this->dbLink->prepare($sql); //使用PDO 需要在执行前先预处理
		$this->PDOStatement->execute($bind);
		$ret = $this->PDOStatement->fetchAll($fetchType);
		$this->rows = count($ret);
		return $ret;
	}
	
	public function execute($sql, $bind=[]){
		if(! $this->dbLink){
			throw new Exception('数据库链接失败');
		}
		$this->PDOStatement = $this->dbLink->prepare($sql); //使用PDO 需要在执行前先预处理
		$ret = $this->PDOStatement->execute($bind);
		
		$this->rows = $this->PDOStatement->rowCount();
		return $ret;
	}
	
	//事务的实现
	public function startTrans(){
		++$this->transTimes;
		if(1 == $this->transTimes){
			$this->dbLink->beginTransaction();
		}else{
			$this->dbLink->execute("SAVEPOINT tr{$this->transTimes}"); //创建一个savepoint
		}
	}
	
	public function commit(){
		if(1 == $this->transTimes){
			$this->dbLink->commit();
		}
		
		--$this->transTimes;
	}
	
	public function rollback(){
		if(1 == $this->transTimes)
		{
			$this->dbLink->rollBack();
		}elseif($this->transTimes>1){
			$this->dbLink->execute("ROLLBACK TO SAVEPOINT tr{$this->transTimes}");
		}
		$this->transTimes = max(0, $this->transTime -1);
	}
	
}
?>